package cn.mjnxin.iot.gate.coder;

import java.util.List;

import cn.mjnxin.iot.base.constant.ConstantValue;
import cn.mjnxin.iot.base.domain.ChannelData;
import cn.mjnxin.iot.base.log.LogWorker;
import cn.mjnxin.iot.gate.cache.GateRuntimeCache;
import cn.mjnxin.iot.gate.util.GateUtil;
import cn.mjnxin.iot.transfer.TransferExchange;
import cn.mjnxin.iot.transfer.TransferExchange.IUnpacker;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * 解码器，将字节形式的报文 解码成对象
 * 
 * 如果当前拦截器没有向out中写入数据 则 后续的handler也不会被执行了
 * 
 * @author CLG 2023年10月10日
 * @version V1.0.0
 */
public class Host2GateDecoder extends ByteToMessageDecoder implements IUnpacker {
	// 日志等级 0：无日志 1：报文长度日志 2：报文内容日志 3：所有日志
	private int logLevel = 0;

	public Host2GateDecoder(int logLevel) {
		this.logLevel  = logLevel;
	}
	
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        TransferExchange.decode(ctx, in, out, this, logLevel);
    }

    public ChannelData unpackOnePackage(Channel channel, ChannelData originData, int type, boolean isIPV4) {
        boolean notTransfer = originData.getType() != ConstantValue.TYPE_HOST_TO_TERMINAL;
        if (notTransfer) {
            // 网关前置交互报文以及业务数据为空的报文不转发
            if (originData.getType() == ConstantValue.TYPE_ALL_HOST_LOGIN_GATE) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("*|Host[%s]Login", originData.getHostAddress()));
                GateUtil.allTerminalLink(originData.getPid(), logLevel, GateRuntimeCache.gateNo, channel);
                GateRuntimeCache.hostLogin(originData.getHostAddress(), channel);
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_CLS_TERMINAL) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("%d|Host[%s]Close Terminal %s", originData.getPid(), originData.getHostAddress(), originData.getTerminalAddress()));
                Channel tchannel = GateRuntimeCache.getTerminal(originData.getTerminalAddress());
                if (tchannel != null) {
                    tchannel.closeFuture();
                    tchannel.close();
                    GateRuntimeCache.terminalUnlink(originData.getTerminalAddress());
                    GateUtil.terminalClosed(originData.getPid(), logLevel, originData.getTerminalAddress(), GateRuntimeCache.gateNo);
                }
                else {
                    GateUtil.terminalClosed(originData.getPid(), logLevel, originData.getTerminalAddress(), GateRuntimeCache.gateNo);
                }
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_MNGALL_LOGIN) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("*|Manage Host[%s]登录", originData.getHostAddress()));
                GateRuntimeCache.setMngChannel(null, originData.getHostAddress(), channel);
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_MNGPID_LOGIN) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("%d|Manage Host[%s]登录", originData.getPid(), originData.getHostAddress()));
                GateRuntimeCache.setMngChannel(originData.getPid(), originData.getHostAddress(), channel);
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_MNG_TERMINAL) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("%d|Host[%s]Manage Terminal[%s]", originData.getPid(), originData.getHostAddress(), originData.getTerminalAddress()));
                GateRuntimeCache.manageTerminal(originData.getTerminalAddress(), originData.getPid());
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_RLS_TERMINAL) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("%d|Host[%s]Release Terminal[%s]", originData.getPid(), originData.getHostAddress(), originData.getTerminalAddress()));
                GateRuntimeCache.releaseTerminal(originData.getTerminalAddress());
            }
            else if (originData.getType() == ConstantValue.TYPE_HOST_LOGIN_GATE) {
            	if (logLevel > 0)
                LogWorker.logForce(String.format("%d|Host[%s]登录", originData.getPid(), originData.getHostAddress()));
                GateRuntimeCache.hostLogin(originData.getPid(), originData.getHostAddress(), channel);
            }
            else {
                LogWorker.logForce("其他未知包");
            }
            return null;
        }

        return originData;
    }
}
